#include<stdio.h>
#include<stdlib.h>
#include<dos.h>
#include <conio.h>
#include<string.h>
struct Info
{
    char name[15];      // 姓名
    char city[10];      // 城市
    char province[10];  // 省
    char state[10];     // 国家
    char tel[15];       // 电话
};
typedef struct node
{
    struct Info data;
    struct node *next;
}Node, *link;

void string_input(char *t, int lens, const char *notice)
{
    char n[50];
    do
    {
        printf("%s", notice);
        scanf("%s", &n);
        if (strlen(n) > lens)
            printf("\n输入的字符串长度超过lens值请重新输入!\n");
    } while (strlen(n)>lens);
    // 输入的字符串拷贝到字符串t中
    strcpy(t, n);
}

void enter(link l)
{
    Node *p, *tail;
    tail = l;
    while (1)
    {
        p = (Node*)malloc(sizeof(Node));    // 申请结点空间
        // 申请失败输出提示消息
        if (!p)
        {
            printf("空间分配失败！");
            return;
        }
        string_input(p->data.name, 15, "输入姓名：");
        // 输入名字是 0 就退出
        if (strcmp(p->data.name, "0") == 0)
            break;
        string_input(p->data.city, 10, "输入城市：");
        string_input(p->data.province, 10, "输入省份：");
        string_input(p->data.state, 10, "输入国家：");
        string_input(p->data.tel, 15, "输入电话号码：");
        // 转换尾节点
        p->next = NULL;
        tail->next = p;
        tail = p;
    }
}
void del(link l)
{
    Node *p, *q;
    // q 是 p 的前置指针
    char s[20];
    q = l;
    p = q->next;
    printf("%s", s);
    scanf("%s", s);     // 输入要删除的姓名
    while (p)
    {
        // 循环查找
        if (strcmp(s, p->data.name) == 0)
        {
            q->next = p->next;
            free(p);
            printf("删除成功!");
            break;
        }
        else
        {
            q = p;
            p = q->next;
        }
    }
    getch();
}
void display(Node *p)
{
    printf("信息\n");
    printf("姓名：%15s\n", p->data.name);
    printf("城市:%10s\n", p->data.city);
    printf("省份:%10s\n", p->data.province);
    printf("国家:%10s\n", p->data.state);
    printf("电话号码:%15s\n", p->data.tel);
}
void search(link l)
{
    char name[20];
    Node *p;
    p = p->next;
    printf("输入您想要找的名字:");
    scanf("%s", name);
    while (p)
    {
        if (strcmp(p->data.name, name) == 0)
        {
            // 符合就显示信息
            display(p);
            getch();
            break;
        }
        else
            p = p->next;
    }
}
void list(link l)
{
    Node *p;
    p = l->next;
    while(p != NULL)
    {
        // 遍历
        display(p);
        p = p->next;
    }
    getch();
}
void save(link l)
{
    Node *p;
    FILE *fp;
    p = l->next;
    if ((fp = fopen("./adresslist.txt", "w")) == NULL)
    {
        printf("无法打开文件!");
        exit(1);
    }

    printf("\n正在保存文件\n");
    // 将节点内容以文本格式写入文件
    while (p)
    {
        fprintf(fp, "%s|%s|%s|%s|%s|%s|%s\n", 
                p->data.name, p->data.city, p->data.province,
                p->data.state, p->data.tel);
        p = p->next;
    }

    fclose(fp);
    printf("保存完成！按任意键继续...");
    getch();
}
void load(link l)
{
    Node *p, *tail;
    FILE *fp;
    l->next = NULL;
    tail = l;
    if ((fp=fopen("./adresslist.txt", "rb")) == NULL)
    {
        printf("无法打开文件！");
        exit(1);
    }
    printf("\n加载文件中\n");
    while(!feof(fp))
    {
        p = (Node*)malloc(sizeof(Node));
        if (!p)
        {
            printf("地址分配完毕！");
            return;
        }
        // 读记录到结点p中
        if (fread(p, sizeof(Node), 1, fp) != 1)
            break;
        else
        {
            // 尾地址切换
            p->next = NULL;
            tail->next = p;
            tail = p;
        }
    }
}
int menu_select()
{
    int i;
    printf("\n****************通讯列表*********************\n");
    printf("|*                1.输入记录              *|\n");
    printf("|*                2.删除记录              *|\n");
    printf("|*                3.列出记录              *|\n");
    printf("|*                4.查找记录              *|\n");
    printf("|*                5.保存记录              *|\n");
    printf("|*                6.加载记录              *|\n");
    printf("|*                7.退出                 *|\n");
    printf("***********************************************\n");
    fflush(stdout);         // 添加这一行刷新输出缓冲区
    do
    {
        printf("\n\t输入你的选择:");
        scanf("%d", &i);
    } while (i<0||i>7);
    return i;
}

int main()
{
    link l;
    l = (Node*)malloc(sizeof(Node));
    if (!l)
    {
        printf("分配空间失败!");
        return 0;
    }
    l->next = NULL;
    system("cls");
    while (1)
    {
        system("cls");
        switch (menu_select())
        {
        case 1:
            enter(l);
            break;
        case 2:
            del(l);
            break;
        case 3:
            list(l);
            break;
        case 4:
            search(l);
            break;
        case 5:
            save(l);
            break;
        case 6:
            load(l);
            break;
        case 7:
            exit(0);
        }
    }
    return 0;
}